using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using SSSGame.Physics;
using WinForm = System.Windows.Forms.Form;
using SSSGame.Forms;
using System.IO;
using System.Security.Cryptography;

namespace SSSGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class SSS : Game
    {
        private Player _player;
        private StreamWriter _log;
        private List<string> _cacheLog = new List<string>();

        // Constructeur
        public SSS()
        {
            _player = new Player(this);            

            this.IsMouseVisible = true;
            Content.RootDirectory = "Content";
            this.IsFixedTimeStep = false;

            _cacheLog.Add("Temps(ms);X;Y;BetaVitesse(deg);OmegaVitesse(deg);Norme Vitesse L(m/s);Norme Vitesse A(deg/s)");

        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            _player._playerContentManager._spriteBatch = new SpriteBatch(GraphicsDevice);
            _player._playerContentManager._star = Content.Load<Texture2D>("starSample");
            _player._playerContentManager._ship = Content.Load<Texture2D>("ship");
            _player._playerContentManager._shipBoost_main = Content.Load<Texture2D>("ship_Boost_main");
            _player._playerContentManager._shipBoost_retro = Content.Load<Texture2D>("ship_Boost_retro");
            _player._playerContentManager._shipRotationHoraire = Content.Load<Texture2D>("ship_RotationHoraire");
            _player._playerContentManager._shipRotationRetrograde = Content.Load<Texture2D>("ship_RotationRetrograde");
            _player._playerContentManager._balise3 = Content.Load<Texture2D>("balise_3");            
            _player._playerContentManager._orientation_poussee = Content.Load<Texture2D>("orientation_poussee");
            _player._playerContentManager._orientation_ship = Content.Load<Texture2D>("orientation_ship");

            _player._playerContentManager._police = Content.Load<SpriteFont>("police");

            _player._playerContentManager._propulseur = Content.Load<SoundEffect>("propulseur");
            _player._playerContentManager._propulseurSoundInstance = _player._playerContentManager._propulseur.CreateInstance();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            //_log = new StreamWriter(Content.RootDirectory + "/Log/log.csv", true);
            //foreach (var item in _cacheLog)
            //{
            //    _log.WriteLine(item);
            //}
            //_log.Close();
            //_log.Dispose();
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            var update = _player.UpdatePlayer(gameTime);

            if (update == Tools.QUITTER)
                Exit();

            if (Keyboard.GetState().IsKeyDown(Keys.L))
                ScreenShot();

            //else if (update == Tools.ECRASERLOG)
            //{
            //    _cacheLog.Clear();
            //    _cacheLog.Add("Temps(ms);X;Y;BetaVitesse(deg);OmegaVitesse(deg);Norme Vitesse L(m/s);Norme Vitesse A(deg/s)");
            //}

            base.Update(gameTime);
        }

        private void ScreenShot()
        {
            var gDevice = _player._playerContentManager._graphics.GraphicsDevice;
            int w = gDevice.PresentationParameters.BackBufferWidth;
            int h = gDevice.PresentationParameters.BackBufferHeight;

            Draw(new GameTime());

            //pull the picture from the buffer 
            int[] backBuffer = new int[w * h];
            gDevice.GetBackBufferData(backBuffer);

            //copy into a texture 
            Texture2D texture = new Texture2D(gDevice, w, h, false, gDevice.PresentationParameters.BackBufferFormat);
            texture.SetData(backBuffer);

            //save to disk 
            Stream stream = File.OpenWrite("sreenTest.jpg");

            texture.SaveAsJpeg(stream, w, h);
            stream.Dispose();
            texture.Dispose();
        }

        private void TracerPosition(
                float x, float y, 
                float betaVitesseLineaire, float omegaVitesseAngulaire,
                float normeVitesseLineaire, float normeVitesseAngulaire,
                double milliseconds)
        {
            //System.Console.WriteLine(string.Format("X : {0}, Y : {1}, BetaVitesse : {2}, OmegaVitesse : {3}", x, y, betaVitesseLineaire, omegaVitesseAngulaire));

            _cacheLog.Add(string.Format("{0};{1};{2};{3};{4};{5};{6}", 
                                         milliseconds, x, y, betaVitesseLineaire, omegaVitesseAngulaire,
                                         normeVitesseLineaire, normeVitesseAngulaire));
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            _player.DrawPlayer();

            //TracerPosition(_player._NouveauVecteurReel.X, _player._NouveauVecteurReel.Y,
            //    MathExtensions.RadToDegrees(_player._PlayerShip._VecteurVitesseLineaire.DonnerBetaVecteur()),
            //    MathExtensions.RadToDegrees(_player._PlayerShip._VecteurVitesseAngulaire.DonnerOmega()),
            //    _player._PlayerShip._VecteurVitesseLineaire.DonnerNorme(),
            //    MathExtensions.RadToDegrees(_player._PlayerShip._VecteurVitesseAngulaire.DonnerNorme()),
            //    gameTime.TotalGameTime.TotalMilliseconds);

            base.Draw(gameTime);
        }
    }
}
